package com.cencat.route.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cencat.route.entity.Delivery;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 配送信息数据访问层
 * 提供配送信息的数据库操作接口
 * 
 * @author cencat
 * @version 1.0
 * @since 2024-01-01
 */
@Mapper
public interface DeliveryMapper extends BaseMapper<Delivery> {

    /**
     * 分页查询配送信息
     */
    Page<Delivery> selectDeliveryPage(Page<Delivery> page, @Param("deliveryCode") String deliveryCode, 
                                     @Param("routeId") Long routeId, @Param("driverId") Long driverId,
                                     @Param("status") String status);

    /**
     * 条件查询配送信息
     */
    List<Delivery> searchDeliveries(@Param("conditions") Map<String, Object> conditions);

    /**
     * 根据配送编号查询配送
     */
    @Select("SELECT * FROM delivery WHERE delivery_code = #{deliveryCode} AND deleted = 0")
    Delivery selectByDeliveryCode(@Param("deliveryCode") String deliveryCode);

    /**
     * 根据路线ID查询配送列表
     */
    @Select("SELECT * FROM delivery WHERE route_id = #{routeId} AND deleted = 0")
    List<Delivery> selectByRouteId(@Param("routeId") Long routeId);

    /**
     * 根据司机ID查询配送列表
     */
    @Select("SELECT * FROM delivery WHERE driver_id = #{driverId} AND deleted = 0")
    List<Delivery> selectByDriverId(@Param("driverId") Long driverId);

    /**
     * 根据配送员ID查询配送列表
     */
    @Select("SELECT * FROM delivery WHERE delivery_man_id = #{deliveryManId} AND deleted = 0")
    List<Delivery> selectByDeliveryManId(@Param("deliveryManId") Long deliveryManId);

    /**
     * 根据状态查询配送列表
     */
    @Select("SELECT * FROM delivery WHERE status = #{status} AND deleted = 0")
    List<Delivery> selectByStatus(@Param("status") String status);

    /**
     * 根据配送类型查询配送列表
     */
    @Select("SELECT * FROM delivery WHERE delivery_type = #{deliveryType} AND deleted = 0")
    List<Delivery> selectByDeliveryType(@Param("deliveryType") String deliveryType);

    /**
     * 批量更新配送状态
     */
    @Update("<script>" +
            "UPDATE delivery SET status = #{status}, updated_time = NOW() " +
            "WHERE id IN " +
            "<foreach collection='ids' item='id' open='(' separator=',' close=')'>" +
            "#{id}" +
            "</foreach>" +
            "</script>")
    int batchUpdateStatus(@Param("ids") List<Long> ids, @Param("status") String status);

    /**
     * 批量更新配送优先级
     */
    @Update("<script>" +
            "UPDATE delivery SET priority = #{priority}, updated_time = NOW() " +
            "WHERE id IN " +
            "<foreach collection='ids' item='id' open='(' separator=',' close=')'>" +
            "#{id}" +
            "</foreach>" +
            "</script>")
    int batchUpdatePriority(@Param("ids") List<Long> ids, @Param("priority") Integer priority);

    /**
     * 批量分配配送员
     */
    @Update("<script>" +
            "UPDATE delivery SET delivery_man_id = #{deliveryManId}, updated_time = NOW() " +
            "WHERE id IN " +
            "<foreach collection='ids' item='id' open='(' separator=',' close=')'>" +
            "#{id}" +
            "</foreach>" +
            "</script>")
    int batchAssignDeliveryMan(@Param("ids") List<Long> ids, @Param("deliveryManId") Long deliveryManId);

    /**
     * 批量更新配送费用
     */
    @Update("<script>" +
            "UPDATE delivery SET delivery_fee = #{deliveryFee}, updated_time = NOW() " +
            "WHERE id IN " +
            "<foreach collection='ids' item='id' open='(' separator=',' close=')'>" +
            "#{id}" +
            "</foreach>" +
            "</script>")
    int batchUpdateDeliveryFee(@Param("ids") List<Long> ids, @Param("deliveryFee") BigDecimal deliveryFee);

    /**
     * 获取配送统计分析
     */
    Map<String, Object> getDeliveryStatistics(@Param("startTime") LocalDateTime startTime, 
                                             @Param("endTime") LocalDateTime endTime);

    /**
     * 智能匹配配送
     */
    List<Delivery> intelligentMatchDeliveries(@Param("conditions") Map<String, Object> conditions);

    /**
     * 查询待配送任务
     */
    @Select("SELECT * FROM delivery WHERE status = 'PENDING' AND deleted = 0 ORDER BY priority DESC, created_time ASC")
    List<Delivery> selectPendingDeliveries();

    /**
     * 查询配送中任务
     */
    @Select("SELECT * FROM delivery WHERE status = 'IN_DELIVERY' AND deleted = 0")
    List<Delivery> selectInDeliveryTasks();

    /**
     * 查询已完成配送
     */
    @Select("SELECT * FROM delivery WHERE status = 'COMPLETED' AND deleted = 0")
    List<Delivery> selectCompletedDeliveries();

    /**
     * 查询已取消配送
     */
    @Select("SELECT * FROM delivery WHERE status = 'CANCELLED' AND deleted = 0")
    List<Delivery> selectCancelledDeliveries();

    /**
     * 查询异常配送
     */
    @Select("SELECT * FROM delivery WHERE status = 'EXCEPTION' AND deleted = 0")
    List<Delivery> selectExceptionDeliveries();

    /**
     * 检查配送是否存在
     */
    @Select("SELECT COUNT(*) > 0 FROM delivery WHERE delivery_code = #{deliveryCode} AND deleted = 0")
    boolean checkDeliveryExists(@Param("deliveryCode") String deliveryCode);

    /**
     * 配送开始
     */
    @Update("UPDATE delivery SET status = 'IN_DELIVERY', start_time = NOW(), updated_time = NOW() WHERE id = #{id}")
    int startDelivery(@Param("id") Long id);

    /**
     * 配送完成
     */
    @Update("UPDATE delivery SET status = 'COMPLETED', end_time = NOW(), updated_time = NOW() WHERE id = #{id}")
    int completeDelivery(@Param("id") Long id);

    /**
     * 配送取消
     */
    @Update("UPDATE delivery SET status = 'CANCELLED', cancel_time = NOW(), updated_time = NOW() WHERE id = #{id}")
    int cancelDelivery(@Param("id") Long id);

    /**
     * 配送异常
     */
    @Update("UPDATE delivery SET status = 'EXCEPTION', exception_time = NOW(), updated_time = NOW() WHERE id = #{id}")
    int exceptionDelivery(@Param("id") Long id);

    /**
     * 配送恢复
     */
    @Update("UPDATE delivery SET status = 'IN_DELIVERY', updated_time = NOW() WHERE id = #{id}")
    int resumeDelivery(@Param("id") Long id);

    /**
     * 更新配送进度
     */
    @Update("UPDATE delivery SET progress = #{progress}, updated_time = NOW() WHERE id = #{id}")
    int updateProgress(@Param("id") Long id, @Param("progress") BigDecimal progress);

    /**
     * 更新配送位置
     */
    @Update("UPDATE delivery SET current_latitude = #{latitude}, current_longitude = #{longitude}, updated_time = NOW() WHERE id = #{id}")
    int updateLocation(@Param("id") Long id, @Param("latitude") BigDecimal latitude, @Param("longitude") BigDecimal longitude);

    /**
     * 获取配送效率统计
     */
    Map<String, Object> getDeliveryEfficiencyStatistics(@Param("startTime") LocalDateTime startTime, 
                                                       @Param("endTime") LocalDateTime endTime);

    /**
     * 获取配送员配送统计
     */
    Map<String, Object> getDeliveryManStatistics(@Param("deliveryManId") Long deliveryManId, 
                                                @Param("startTime") LocalDateTime startTime, 
                                                @Param("endTime") LocalDateTime endTime);

    /**
     * 获取路线配送统计
     */
    Map<String, Object> getRouteDeliveryStatistics(@Param("routeId") Long routeId, 
                                                  @Param("startTime") LocalDateTime startTime, 
                                                  @Param("endTime") LocalDateTime endTime);

    /**
     * 根据时间范围查询配送
     */
    List<Delivery> selectByTimeRange(@Param("startTime") LocalDateTime startTime, 
                                    @Param("endTime") LocalDateTime endTime);

    /**
     * 根据优先级查询配送
     */
    List<Delivery> selectByPriority(@Param("minPriority") Integer minPriority, 
                                   @Param("maxPriority") Integer maxPriority);

    /**
     * 查询紧急配送
     */
    @Select("SELECT * FROM delivery WHERE urgent = 1 AND deleted = 0 ORDER BY priority DESC")
    List<Delivery> selectUrgentDeliveries();

    /**
     * 查询延期配送
     */
    @Select("SELECT * FROM delivery WHERE status IN ('PENDING', 'IN_DELIVERY') AND planned_end_time < NOW() AND deleted = 0")
    List<Delivery> selectOverdueDeliveries();

    /**
     * 查询附近配送
     */
    List<Delivery> selectNearbyDeliveries(@Param("latitude") BigDecimal latitude, 
                                         @Param("longitude") BigDecimal longitude, 
                                         @Param("radius") BigDecimal radius);

    /**
     * 查询同城配送
     */
    @Select("SELECT * FROM delivery WHERE delivery_city = #{city} AND deleted = 0")
    List<Delivery> selectSameCityDeliveries(@Param("city") String city);

    /**
     * 查询跨城配送
     */
    @Select("SELECT * FROM delivery WHERE delivery_city != pickup_city AND deleted = 0")
    List<Delivery> selectCrossCityDeliveries();

    /**
     * 配送员注册
     */
    int registerDeliveryMan(@Param("deliveryMan") Map<String, Object> deliveryMan);

    /**
     * 配送员认证
     */
    @Update("UPDATE delivery_man SET verified = 1, verified_time = NOW(), updated_time = NOW() WHERE id = #{id}")
    int verifyDeliveryMan(@Param("id") Long id);

    /**
     * 获取配送收入统计
     */
    Map<String, Object> getDeliveryIncomeStatistics(@Param("deliveryManId") Long deliveryManId, 
                                                   @Param("startTime") LocalDateTime startTime, 
                                                   @Param("endTime") LocalDateTime endTime);

    /**
     * 获取配送评分统计
     */
    Map<String, Object> getDeliveryRatingStatistics(@Param("deliveryId") Long deliveryId);

    /**
     * 自动分配最优配送员
     */
    Long autoAssignOptimalDeliveryMan(@Param("deliveryId") Long deliveryId, @Param("conditions") Map<String, Object> conditions);
}